<template>
  <div class="page-container">
    <el-container>
      <div :class="!btnList || btnList.length === 0 && !showQuery ? 'flex-div-mini' : 'flex-div'">
        <el-button type="primary" :icon="flexIcon" :class="!btnList || btnList.length === 0 && !showQuery ? 'flex-button-mini' : 'flex-button'" :title="flexTitle" @click="queryChange" />
      </div>
      <el-header :height="showQuery?'41px':'0'" class="query-header">
        <el-collapse-transition>
          <div v-show="showQuery">
            <span>用户名：</span>
            <el-input v-model="name" placeholder="请输用户名" class="mr-15 width-180" clearable />
            <span>状态：</span>
            <el-select v-model="state" class="width-160">
              <el-option label="全部" value="" />
              <el-option v-for="item in stateList" :key="item.dictId" :value="item.dictCode" :label="item.dictName" />
            </el-select>
            <QueryButton @query="query" @reset="reset" />
          </div>
        </el-collapse-transition>
      </el-header>
      <el-container>
        <el-header :height="!btnList || btnList.length === 0 ? '0' : '43px'" class="operation-header">
          <OperationBtn :btn-list="btnList" @handleClickBtn="handleClickBtn" />
        </el-header>
        <el-main class="page-main">
          <el-table
            ref="simpleTable"
            v-loading="tableLoading"
            :data="tableData"
            border
            highlight-current-row
            class="table-style"
            :height="tableHeight"
            @row-click="rowClick"
          >
            <el-table-column label="选择" align="center" width="55px"><template slot-scope="{ row }"><el-radio v-model="tableRadio" :label="row" @click.native="rowClick"><i /></el-radio></template></el-table-column>
            <el-table-column prop="name" label="账号名" min-width="14%" align="center" show-overflow-tooltip />
            <el-table-column prop="alias" label="用户名" min-width="16%" align="center" show-overflow-tooltip />
            <el-table-column prop="phone" label="手机号码" min-width="15%" align="center" />
            <el-table-column prop="email" label="邮箱" min-width="16%" align="center" show-overflow-tooltip />
            <el-table-column prop="roles" label="角色" min-width="20%" align="center" show-overflow-tooltip />
            <el-table-column prop="activeName" label="状态" width="65" align="center" />
          </el-table>
          <el-pagination
            :total="total"
            :page-size="pageSize"
            :page-sizes="[10, 20, 30, 40, 50]"
            :current-page="currentPage"
            layout="total, sizes, prev, pager, next, jumper, slot"
            @current-change="handleCurrentChange"
            @size-change="handleSizeChange"
          >
            <el-button class="refresh-button" icon="el-icon-refresh" title="刷新" @click="refresh" />
          </el-pagination>
        </el-main>
      </el-container>
    </el-container>
    <!-- 新增、修改对话框 -->
    <el-dialog :visible.sync="addDlgVisible" :title="addDlgTitle" width="390px" class="add-user-dialog" :close-on-click-modal="false" @close="cancel('addForm')">
      <el-form ref="addForm" :model="addForm" :rules="formRules" class="add-form">
        <el-form-item prop="name">
          <span class="add-form-span">账号名：</span>
          <el-input v-model="addForm.name" class="add-form-input" maxlength="30" placeholder="不支持特殊符号" :disabled="addDlgTitle === '修改'" show-word-limit />
        </el-form-item>
        <el-form-item prop="alias">
          <span class="add-form-span">用户名：</span>
          <el-input v-model="addForm.alias" class="add-form-input" maxlength="30" show-word-limit placeholder="不支持特殊符号" />
        </el-form-item>
        <el-form-item prop="phone">
          <span class="add-form-span">手机号码：</span>
          <el-input v-model="addForm.phone" maxlength="15" class="add-form-input" show-word-limit @input="e => addForm.phone = validForbid (e)" @keyup.native="addForm.phone = addForm.phone.replace(/\D/g,'')" />
        </el-form-item>
        <el-form-item prop="email">
          <span class="add-form-span">电子邮箱：</span>
          <el-input v-model="addForm.email" class="add-form-input" maxlength="30" show-word-limit />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="cancel('addForm')">取消</el-button>
        <el-button plain type="primary" :disabled="addBtnDisable" @click="addUser">确定</el-button>
      </div>
    </el-dialog>

    <!-- 角色配置页面 -->
    <el-dialog
      title="角色配置"
      :close-on-click-modal="false"
      :visible.sync="roleConfigVisible"
      class="attribute-dialog"
      width="600px"
    >
      <span class="config-title">{{ userName }}</span>
      <transfer-form
        v-if="roleConfigVisible"
        left-title="可选角色"
        right-title="已选角色"
        :search="false"
        :operation-btn="attributeBtn"
        @add="addRole(0)"
        @cancel="addRole(1)"
      >
        <div slot="left-list">
          <template>
            <el-button v-for="item in leftRole" :key="item.roleId" type="text" class="report-list" :title="item.roleName" :class="buttonActive === item.roleId ? 'active' : 'normal'" @click="roleChoose(item, 0)">{{ item.roleName }}</el-button>
          </template>
        </div>
        <div slot="right-list">
          <no-content v-if="rightRole.length === 0" />
          <template>
            <el-button v-for="item in rightRole" :key="item.roleId" type="text" class="report-list" :title="item.roleName" :class="buttonActive === item.roleId ? 'active' : 'normal'" @click="roleChoose(item, 1)">{{ item.roleName }}</el-button>
          </template>
        </div>
      </transfer-form>
      <div slot="footer">
        <el-button @click="roleConfigVisible=false">关闭</el-button>
      </div>
    </el-dialog>
    <!-- 操作记录 -->
    <OperationDlg :show.sync="recordDlg" :record-table="recordTable" />
  </div>
</template>

<script>
import { OperationBtn, QueryButton, TransferForm, OperationDlg, NoContent } from '../../components/index'
import API from '@/utils/api/baseData/userManage'
import publicAPI from '@/utils/api/public/public'
import common from '@/common/common'
import { getDictData } from '@/common/getDictData'

export default {
  name: 'User',
  components: { OperationBtn, QueryButton, TransferForm, OperationDlg, NoContent },
  data() {
    const phoneValidate = (rule, value, callback) => {
      const reg = new RegExp(/(^1\d{10}$)|(^[0-9]\d{7}$)/)
      if (value === '' || value === null) {
        callback()
      } else if (value.length !== 11 && value.length !== 0) {
        callback(new Error('*请输入正确的手机号码'))
      } else if (!reg.test(value)) {
        callback(new Error('*手机号码格式不正确'))
      } else {
        callback()
      }
    }
    return {
      name: '',
      state: '',
      stateList: [],
      tableData: [],
      tableRadio: [],
      total: 0,
      pageSize: 10,
      currentPage: 1,
      addForm: {
        name: '',
        alias: '',
        phone: '',
        email: '',
        _csrf: sessionStorage._csrf
      },
      formRules: {
        name: [
          { required: true, message: '*请输入账号名' },
          { validator: common.validateForm().specialWord, trigger: ['blur', 'change'] },
          { validator: common.validateForm().Chinese, trigger: ['blur', 'change'] }
        ],
        alias: [{ required: true, message: '*请输入用户名' }, { validator: common.validateForm().specialWord, trigger: ['blur', 'change'] }],
        phone: [{ validator: phoneValidate, trigger: 'change' }],
        email: [{ type: 'email', message: '*请输入正确的邮箱' }]
      },
      addDlgVisible: false,
      addDlgTitle: '新增',
      roleConfigVisible: false, // 角色配置页面是否显示
      userName: '',
      buttonActive: '',
      hasConfig: 0,
      recordDlg: false,
      recordTable: [],
      flexTitle: '点击收起查询栏',
      flexIcon: 'el-icon-arrow-up',
      showQuery: true,
      tableHeight: '414',
      attributeBtn: [], // 角色配置按钮
      configBtn: [], // 属性配置按钮
      tableLoading: false,
      addBtnDisable: false,
      leftRole: [],
      rightRole: []
    }
  },
  computed: {
    btnList() {
      return common.getBtn(this.$route.path)
    }
  },
  watch: {
    showQuery() {
      this.getTableHeight()
    },
    roleConfigVisible(val) {
      if (!val) {
        this.getTableData()
      }
    },
    tableRadio(val) {
      this.$nextTick(() => {
        const row = val && val.length !== 0 ? val : null
        this.$refs.simpleTable.setCurrentRow(row)
      })
    }
  },
  created() {
    this.getTableData()
    getDictData({ dictType: 'ACTIVE_TYPE' }).then(res => {
      this.stateList = res
      if (this.stateList.length === 1) {
        this.state = this.stateList[0].dictCode
      }
    }) // 获取状态列表
    this.defaultAddForm = common.deepCopy(this.addForm)
  },
  mounted() {
    this.$nextTick(() => {
      this.getTableHeight()
    })
    window.addEventListener('resize', this.getTableHeight)
  },
  activated() {
    this.$refs.simpleTable.doLayout() // 重新计算表格布局，防止高度没占满就出现滚动条
  },
  destroyed() {
    window.removeEventListener('resize', this.getTableHeight)
  },
  methods: {
    // 获取表格高度
    getTableHeight: function() {
      this.tableHeight = common.getTableHeight(this.showQuery, this.btnList)
    },
    // 收缩、展示查询栏
    queryChange: function() {
      this.showQuery = !this.showQuery
      this.flexTitle = this.showQuery ? '点击收起查询栏' : '点击展开查询栏'
      this.flexIcon = this.showQuery ? 'el-icon-arrow-up' : 'el-icon-arrow-down'
    },
    // 按钮点击事件
    handleClickBtn: function(val) {
      this.btnList.forEach(btn => {
        const btnUrl = btn.componentName.split('/')
        if (btnUrl[btnUrl.length - 1] === val) {
          this.attributeBtn = btn.childButtonMenuInfoTreeSet
        }
      })
      switch (val) {
        case 'add':
        case 'update':
          this.addDlg(val)
          break
        case 'reset':
          this.pwdReset()
          break
        case 'enable':
        case 'forbidden':
          this.enable(val)
          break
        case 'role':
          this.roleConfigDlg()
          break
        case 'operationRecord':
          this.operationRecord()
          break
        default:
          this.$warnMsg('未配置该功能')
          break
      }
    },
    // 查询
    query: function() {
      this.currentPage = 1
      this.tableRadio = []
      this.getTableData()
    },
    // 重置
    reset: function() {
      this.name = ''
      this.state = ''
    },
    // 刷新
    refresh: function() {
      this.getTableData()
    },
    // 换页
    handleCurrentChange: function(val) {
      this.currentPage = val
      this.getTableData()
    },
    // 每页显示数量
    handleSizeChange: function(val) {
      this.pageSize = val
      setTimeout(() => { this.getTableData() }, 0)
    },
    // 表格行点击事件
    rowClick: function(item) {
      if (this.tableRadio === item) {
        this.tableRadio = []
      } else {
        this.tableRadio = item
        this.userName = item.alias
      }
    },
    // 打开新增、修改对话框
    addDlg: function(val) {
      this.addBtnDisable = false
      if (val === 'add') {
        this.addDlgTitle = '新增'
        this.addForm = Object.assign({
          name: '',
          alias: '',
          phone: '',
          email: '',
          _csrf: sessionStorage._csrf
        })
        this.$nextTick(() => { this.$refs.addForm.clearValidate() })
        this.addDlgVisible = true
      } else {
        const row = this.tableRadio
        if (row.length === 0) {
          this.$warnMsg('请选择要修改的用户')
        } else {
          this.addDlgTitle = '修改'
          this.addForm = Object.assign({}, row)
          this.addDlgVisible = true
        }
      }
    },
    // 表单重置
    cancel: function(form) {
      this.addForm = common.deepCopy(this.defaultAddForm)
      this.$refs[form].clearValidate()
      this.addDlgVisible = false
    },
    // 新增用户
    addUser: function() {
      this.$refs.addForm.validate(valid => {
        if (valid) {
          this.addBtnDisable = true
          if (this.addDlgTitle === '新增') {
            API.addUserAPI(this.addForm).then(response => {
              const res = response.data.data
              if (response.data.flag === 'success') {
                this.$successMsg('新增用户成功')
                this.cancel('addForm')
                this.getTableData()
              } else {
                this.$errorMsg(res)
                this.addBtnDisable = false
              }
            }).catch(error => {
              this.$errorMsg('' + error)
              this.addBtnDisable = false
            })
          } else {
            const { userId, alias, phone, email, name } = this.addForm
            const params = { userId, alias, phone, email, _csrf: sessionStorage._csrf }
            API.updateUserAPI(params).then(response => {
              const res = response.data.data
              if (response.data.flag === 'success') {
                this.$successMsg('用户"' + name + '"信息修改成功')
                this.getTableData()
                this.cancel('addForm')
              } else {
                this.$errorMsg(res)
                this.addBtnDisable = false
              }
            }).catch(error => {
              this.$errorMsg('' + error)
              this.addBtnDisable = false
            })
          }
        }
      })
    },
    // 密码重置
    pwdReset: function() {
      const row = this.tableRadio
      if (row.length === 0) {
        this.$warnMsg('请选择要重置密码的用户')
      } else {
        const params = {
          userId: row.userId,
          _csrf: sessionStorage._csrf
        }
        API.resetPwdAPI(params).then(response => {
          const res = response.data.data
          if (response.data.flag === 'success') {
            this.$successMsg('用户"' + row.name + '"重置密码成功')
          } else {
            this.$errorMsg(res)
          }
        }).catch(error => { this.$errorMsg('' + error) })
      }
    },
    // 启用、禁用
    enable: function(val) {
      const row = this.tableRadio
      const label = val === 'enable' ? '启用' : '禁用'
      const rowState = row.state === 1 ? '启用' : '禁用'
      if (row.length === 0) {
        this.$warnMsg('请选择要' + label + '的数据')
      } else {
        if (rowState === label) {
          this.$errorMsg(label + '失败，该用户已经是' + label + '状态')
        } else {
          const params = {
            userId: row.userId,
            _csrf: sessionStorage._csrf
          }
          API.userEnableAPI(val, params).then(response => {
            const res = response.data.data
            if (response.data.flag === 'success') {
              this.$successMsg('用户"' + row.name + '"' + label + '成功')
              // 重置页码
              if ((this.state === '0' && val === 'enable') || (this.state === '1' && val === 'forbidden')) {
                const totalPage = Math.ceil((this.total - 1) / this.pageSize)
                const currentPage = this.currentPage > totalPage ? totalPage : this.currentPage
                this.currentPage = currentPage < 1 ? 1 : currentPage
              }
              this.getTableData()
            } else {
              this.$errorMsg(res)
            }
          }).catch(error => { this.$errorMsg('' + error) })
        }
      }
    },
    // 获取页面表格
    getTableData: function() {
      this.tableLoading = true
      const { state, name, currentPage, pageSize } = this
      const params = {
        active: state,
        alias: name,
        page: currentPage,
        rows: pageSize
      }
      API.userListAPI(params).then(response => {
        const res = response.data.data
        if (response.data.flag === 'success') {
          this.tableData = res.content
          this.total = res.total
          this.tableData.forEach(row => {
            if (row.userId === this.tableRadio.userId) {
              this.tableRadio = row
              return
            }
          })
        } else {
          this.$errorMsg(res)
        }
        this.tableLoading = false
      }).catch(error => {
        this.$errorMsg('' + error)
        this.tableLoading = false
      })
    },
    // 打开用户配置对话框
    roleConfigDlg: function() {
      this.buttonActive = ''
      if (this.tableRadio.length === 0) {
        this.$warnMsg('请选择要配置的用户')
      } else {
        this.getRoleList(1)
        this.getRoleList(0)
        this.roleConfigVisible = true
      }
    },
    // 左列表选中某个出单中心或角色
    roleChoose: function(item, type) {
      this.buttonActive = item.roleId
      this.hasConfig = type
    },
    // 获取可选角色和已配置角色列表
    getRoleList: function(val) {
      const isCheck = val === 1 ? 'Y' : 'N'
      const { userId } = this.tableRadio
      const params = { userId, isCheck }
      API.roleListAPI(params).then(response => {
        const res = response.data.data
        if (response.data.flag === 'success') {
          if (val === 1) { // 已配置的角色
            this.rightRole = res
          } else { // 可选的角色
            this.leftRole = res
          }
        } else {
          this.$errorMsg(res)
        }
      }).catch(error => { this.$errorMsg('' + error) })
    },
    // 角色配置 - 添加、删除
    addRole: function(type) {
      const label = type === 1 ? '删除' : '添加'
      if (this.hasConfig === type) {
        if (!this.buttonActive) {
          this.$warnMsg('请选择要' + label + '的角色')
        } else {
          const url = type === 1 ? 'deleteUserRoles' : 'addUserRoles'
          const params = {
            userId: this.tableRadio.userId,
            roleId: this.buttonActive,
            _csrf: sessionStorage._csrf
          }
          API.addRoleAPI(url, params).then(response => {
            const res = response.data.data
            if (response.data.flag === 'success') {
              this.$successMsg(label + '成功')
              this.getRoleList(1)
              this.getRoleList(0)
              this.buttonActive = ''
            } else {
              this.$errorMsg(res)
            }
          }).catch(error => { this.$errorMsg('' + error) })
        }
      } else {
        this.$warnMsg('请选择要' + label + '的角色')
      }
    },
    // 操作记录
    operationRecord: function() {
      const row = this.tableRadio
      if (row === null || row.length === 0) {
        this.$warnMsg('请选择要查看操作记录的数据')
      } else {
        this.recordDlg = true
        publicAPI.operationDataAPI({ dataId: row.userId }).then(response => {
          this.recordTable = response.data.content
        }).catch(error => { this.$errorMsg(error) })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.query-header {
  min-width: 760px;
  transition: 0.5s;
  div:nth-child(1) {
    padding: 7px 0 3px 0;
  }
}
.operation-header {
  line-height: 43px;
  border-bottom: solid 1px #c1defa;
  min-width: 610px;
}
.page-main {
  padding: 5px 5px 0px 5px;
}
.add-form-span {
  display: inline-block;
  width: 80px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.add-form-input {
  width: 200px;
}
.config-title {
  display: inline-block;
  width: 100%;
  line-height: 28px;
  font-size: 16px;
  text-align: center;
  margin-bottom: 7px;
}
.report-list {
  width: 100%;
  margin: 1px 0px;
  border-radius: 0px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
  padding: 5px 5px;
  font-size: 14px;
}
.active {
  background-color: #6fb0e6;
  color: white;
}
.normal {
  color: #44484bc4;
}
.flex-div {
  width: 36px;
  height: 36px;
  text-align: center;
  line-height: 36px;
  position: absolute;
  right: 10px;
  z-index: 1000; // wsq 查询栏收缩按钮悬浮到上层，解决收起查询栏时按钮被覆盖的问题
  transition: 0.5s;
}
.flex-button {
  padding: 0;
  width: 36px;
  height: 36px;
  transition: 0.5s;
}
.flex-div-mini {
  width: 36px;
  height: 18px;
  text-align: center;
  line-height: 18px;
  position: absolute;
  right: 10px;
  z-index: 1000; // wsq 查询栏收缩按钮悬浮到上层，解决收起查询栏时按钮被覆盖的问题
}
.flex-button-mini {
  padding: 0;
  width: 36px;
  height: 18px;
}
.flex-div:hover {
  background-color: rgba(167, 210, 255, 0.267);
  border-radius: 6px;
}
.table-style {
  transition: 0.5s;
}
</style>
<style lang="scss">
.add-user-dialog {
  .el-dialog__body {
    padding: 10px 20px 0px 30px;
  }
}
.add-form {
  .el-form-item__error {
    margin-left: 80px;
  }
}
.attribute-dialog {
  .el-dialog__header {
    padding-bottom: 0;
  }
  .el-dialog__body {
    padding: 2px 20px;
  }
  .report-list:hover,
  .report-list:focus {
    background-color: #6fb0e6;
    color: aliceblue;
  }
}
</style>
